package com.zl.tby.core.base.util;

import com.fasterxml.jackson.core.PrettyPrinter;
import com.zl.tby.core.base.bean.OptionType;
import com.zl.tby.core.common.User;
import com.zl.tby.model.TbySpeciesCategory;
import org.noear.wood.utils.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.Year;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;

/**
 * @author changpeng
 * @version 1.0
 * @since 2024/8/6 20:29
 */
public class ToolsUtil {

    public static Long getLoginUserId() {
        try {
            User user = User.current();
            return user == null ? -1L : user.getUserId();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return -1L;
    }

    public static Long toLong(String word, Long defaultValue) {
        try {
            return Long.parseLong(word);
        } catch (Exception ex) {
            return defaultValue;
        }
    }

    /**
     * 分隔字符串为数组
     *
     * @param str
     * @param c
     * @return
     */
    public static String[] splitStr(String str, char c) {
        if (str == null) {
            return null;
        }
        str += c;
        int n = 0;
        for (int i = 0; i < str.length(); i++) {
            if (str.charAt(i) == c) {
                n++;
            }
        }
        String[] out = new String[n];
        for (int i = 0; i < n; i++) {
            int index = str.indexOf(c);
            out[i] = str.substring(0, index);
            str = str.substring(index + 1, str.length());
        }
        return out;
    }

    public static <T> List<T> emptyIfNull(List<T> set) {
        return null == set ? Collections.emptyList() : set;
    }

    public static Date dateString2Util(String dateStr, String format) {
        if(StringUtils.isEmpty(dateStr)){
            return null;
        }
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        return formatter.parse(dateStr, new ParsePosition(0));
    }

    public static String dateUtil2String(Date date, String format) {
        if (date == null) {
            return null;
        }
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        return formatter.format(date);
    }

    public static BigDecimal divide(BigDecimal arg1 , BigDecimal arg2, int roundNum){
        if(arg2.compareTo(new BigDecimal(0)) == 0){
            return new BigDecimal(0);
        }
        return arg1.divide(arg2, roundNum, RoundingMode.HALF_UP);
    }

    public static BigDecimal add(BigDecimal arg1 , BigDecimal arg2){
        return arg1.add(arg2);
    }

    /**
     * 比较两个日期的年份
     * @param start: 开始时间
     * @param end：结束时间
     * @return 结果
     */
    public static long calBetweenYear(Date start, Date end) {
        LocalDate startTime = start.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDate endTime = end.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        return ChronoUnit.YEARS.between(startTime, endTime);
    }

    /**
     * 比较两个日期的日期
     * @param start: 开始时间
     * @param end：结束时间
     * @return 结果
     */
    public static long calBetweenDay(Date start, Date end) {
        LocalDate startTime = start.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDate endTime = end.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        return ChronoUnit.DAYS.between(startTime, endTime);
    }

    public static String fillLength(String original, int desiredLength) {
        return String.format("%0" + desiredLength + "d", Integer.parseInt(original));
    }

    public static String replaceStr(String source, String oldString, String newString) {
        if(source == null) {
            return source;
        }
        StringBuffer output = new StringBuffer();
        int lengthOfSource = source.length();
        int lengthOfOld = oldString.length();
        int posStart = 0;
        int pos;
        String lower_s=source.toLowerCase();
        String lower_o=oldString.toLowerCase();
        while ((pos = lower_s.indexOf(lower_o, posStart)) >= 0) {
            output.append(source.substring(posStart, pos));
            output.append(newString);
            posStart = pos + lengthOfOld;
        }
        if (posStart < lengthOfSource) {
            output.append(source.substring(posStart));
        }
        return output.toString();
    }

    public static boolean isNotNull(Object obj) {
        return obj != null;
    }

    public static int getYear() {
        return new GregorianCalendar().get(Calendar.YEAR);
    }

    public static List<LocalDate> getDatesBetween(LocalDate startDate, LocalDate endDate) {
        List<LocalDate> dates = new ArrayList<>();
        while (!startDate.isAfter(endDate)) {
            dates.add(startDate);
            startDate = startDate.plusDays(1);
        }
        return dates;
    }

    public static List<LocalDate> getMonthBetween(LocalDate startDate, LocalDate endDate) {
        List<LocalDate> dates = new ArrayList<>();
        while (!startDate.isAfter(endDate)) {
            dates.add(startDate);
            startDate = startDate.plusMonths(1);
        }
        return dates;
    }

    public static String getChineseDate(Date time) {
        int week = getWeekOfDate(time);
        String value = "";
        if (week == 1) { value = "一"; }
        else if (week == 2) { value = "二"; }
        else if (week == 3) { value = "三"; }
        else if (week == 4) { value = "四"; }
        else if (week == 5) { value = "五"; }
        else if (week == 6) { value = "六"; }
        else if (week == 7) { value = "日"; }
        return dateUtil2String(new Date(System.currentTimeMillis()), "yyyy年MM月dd日") + "星期" + value;
    }

    public static int getWeekOfDate(Date dt) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(dt);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w <= 0) {
            w = 7;
        }
        return w;
    }

    public static String getWeekODateChinese(Date dt) {
        int week = getWeekOfDate(dt);
        String value = "";
        if (week == 1) { value = "一"; }
        else if (week == 2) { value = "二"; }
        else if (week == 3) { value = "三"; }
        else if (week == 4) { value = "四"; }
        else if (week == 5) { value = "五"; }
        else if (week == 6) { value = "六"; }
        else if (week == 7) { value = "日"; }
        return "星期" + value;
    }

    public static void whileFindId(List<TbySpeciesCategory> dataList, Long parentId, List<Long> idList) {
        for (TbySpeciesCategory entity : dataList) {
            Long dbParentId = entity.getParentId();
            if (dbParentId.compareTo(parentId) == 0) {
                idList.add(entity.getId());
                whileFindId(dataList, entity.getId(), idList);
            }
        }
    }

    private static final String[] directArrOne = new String[] {
            "北", "东北", "东北", "东北",
            "东", "东南", "东南", "东南",
            "南", "西南", "西南", "西南",
            "西", "西北", "西北", "西北"
    };

    public static String windDirectionSwitch(float degrees) {
        int index = 0;
        if (348.75 <= degrees && degrees <= 360) {
            index = 0;
        } else if (0 <= degrees && degrees <= 11.25) {
            index = 0;
        } else if (11.25 < degrees && degrees <= 33.75) {
            index = 1;
        } else if (33.75 < degrees && degrees <= 56.25) {
            index = 2;
        } else if (56.25 < degrees && degrees <= 78.75) {
            index = 3;
        } else if (78.75 < degrees && degrees <= 101.25) {
            index = 4;
        } else if (101.25 < degrees && degrees <= 123.75) {
            index = 5;
        } else if (123.75 < degrees && degrees <= 146.25) {
            index = 6;
        } else if (146.25 < degrees && degrees <= 168.75) {
            index = 7;
        } else if (168.75 < degrees && degrees <= 191.25) {
            index = 8;
        } else if (191.25 < degrees && degrees <= 213.75) {
            index = 9;
        } else if (213.75 < degrees && degrees <= 236.25) {
            index = 10;
        } else if (236.25 < degrees && degrees <= 258.75) {
            index = 11;
        } else if (258.75 < degrees && degrees <= 281.25) {
            index = 12;
        } else if (281.25 < degrees && degrees <= 303.75) {
            index = 13;
        } else if (303.75 < degrees && degrees <= 326.25) {
            index = 14;
        } else if (326.25 < degrees && degrees < 348.75) {
            index = 15;
        } else {
            index = 0;
        }
        return directArrOne[index];
    }

    public static Integer getLuxLevel(BigDecimal lux) {
        if (lux.compareTo(new BigDecimal(5)) < 0) {
            return 1;
        } else if (lux.compareTo(new BigDecimal(5)) >= 0 && lux.compareTo(new BigDecimal(10)) <= 0) {
            return 2;
        } else if (lux.compareTo(new BigDecimal(10)) >= 0 && lux.compareTo(new BigDecimal(15)) <= 0) {
            return 3;
        } else if (lux.compareTo(new BigDecimal(15)) >= 0 && lux.compareTo(new BigDecimal(30)) <= 0) {
            return 4;
        }
        return 5;
    }

    public static String getAQI(BigDecimal value) {
        if (value.compareTo(new BigDecimal(35)) > 0 && value.compareTo(new BigDecimal(75)) <= 0) {
            return "良";
        } else if (value.compareTo(new BigDecimal(75)) > 0 && value.compareTo(new BigDecimal(115)) <= 0) {
            return "轻度";
        } else if (value.compareTo(new BigDecimal(115)) > 0 && value.compareTo(new BigDecimal(150)) <= 0) {
            return "中度";
        } else if (value.compareTo(new BigDecimal(150)) > 0 && value.compareTo(new BigDecimal(250)) <= 0) {
            return "重度";
        } else if (value.compareTo(new BigDecimal(250)) > 0) {
            return "严重";
        }
        return "优";
    }

    public static String getWeatherText(BigDecimal rain, BigDecimal luxDecimal) {
        if (rain.compareTo(new BigDecimal(0)) > 0) {
            return "雨天";
        } else if (luxDecimal != null) {
            BigDecimal value = luxDecimal.multiply(new BigDecimal(126.58));
            if (value.compareTo(new BigDecimal(10000)) > 0) {
               return "晴天";
            } else if (value.compareTo(new BigDecimal(1000)) > 0 && value.compareTo(new BigDecimal(10000)) <= 0) {
                return "多云";
            } else if (value.compareTo(new BigDecimal(10)) > 0 && value.compareTo(new BigDecimal(1000)) <= 0) {
                return "阴天";
            }  else if (value.compareTo(new BigDecimal(10)) <= 0) {
                return "黑夜";
            }
        }
        return "晴天";
    }

    public static void main(String[] args) {
        Date fromDate = ToolsUtil.dateString2Util("1988-12-26 00:00:00", "yyyy-MM-dd HH:mm:ss");
        Date toDate = ToolsUtil.dateString2Util("2024-11-27 00:00:00", "yyyy-MM-dd HH:mm:ss");
        Calendar  from  =  Calendar.getInstance();
        from.setTime(fromDate);
        Calendar  to  =  Calendar.getInstance();
        to.setTime(toDate);

        long years = ChronoUnit.YEARS.between(fromDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(),
                toDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
        int yearDay = Year.of(2024).length();
        int fromDay = from.get(Calendar.DAY_OF_YEAR);
        int toDay = to.get(Calendar.DAY_OF_YEAR);
        int day = toDay  - fromDay;
        if (day < 0) {
            day = yearDay + day;
        }
        System.out.println(years + " " + day);
    }

    public static Integer getWindPower(BigDecimal windSpeed) {
        if (windSpeed.compareTo(new BigDecimal(0.3)) >= 0 && windSpeed.compareTo(new BigDecimal(1.6)) < 0) {
            return 1;
        } else if (windSpeed.compareTo(new BigDecimal(1.6)) >= 0 && windSpeed.compareTo(new BigDecimal(3.4)) < 0) {
            return 2;
        } else if (windSpeed.compareTo(new BigDecimal(3.4)) >= 0 && windSpeed.compareTo(new BigDecimal(5.5)) < 0) {
            return 3;
        } else if (windSpeed.compareTo(new BigDecimal(5.5)) >= 0 && windSpeed.compareTo(new BigDecimal(8)) < 0) {
            return 4;
        } else if (windSpeed.compareTo(new BigDecimal(8)) >= 0 && windSpeed.compareTo(new BigDecimal(10.8)) < 0) {
            return 5;
        } else if (windSpeed.compareTo(new BigDecimal(10.8)) >= 0 && windSpeed.compareTo(new BigDecimal(13.9)) < 0) {
            return 6;
        } else if (windSpeed.compareTo(new BigDecimal(13.9)) >= 0 && windSpeed.compareTo(new BigDecimal(17.2)) < 0) {
            return 7;
        } else if (windSpeed.compareTo(new BigDecimal(17.2)) >= 0 && windSpeed.compareTo(new BigDecimal(20.8)) < 0) {
            return 8;
        } else if (windSpeed.compareTo(new BigDecimal(20.8)) >= 0 && windSpeed.compareTo(new BigDecimal(24.4)) < 0) {
            return 9;
        }
        return 0;
    }

    public static int getMonthDifference(Date startDate, Date endDate) {
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTimeInMillis(startDate.getTime());
        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTimeInMillis(endDate.getTime());
        int yearDiff = calendar2.get(Calendar.YEAR) - calendar1.get(Calendar.YEAR);
        int monthDiff = calendar2.get(Calendar.MONTH) - calendar1.get(Calendar.MONTH);
        return monthDiff + yearDiff * 12;
    }

    public static String addPreAndFix(String value, String pre, String fix, String defaultValue) {
        if (StringUtils.isEmpty(value)) {
            return defaultValue;
        }
        if (!value.startsWith(pre)) {
            value = pre + value;
        }
        if (!value.endsWith(fix)) {
            value = value + fix;
        }
        return value;
    }
}
